{
    "AWSTemplateFormatVersion": "2010-09-09",
    "Description": "Identify resource(s) stack creation using Amplify CLI",
    "Parameters": {
        "resourceName": {
            "Type": "String"
        },
        "identifyPolicyName": {
            "Type": "String"
        },
        "access": {
            "Type": "String"
        },
        "authRoleName": {
			"Type": "String"
		},
        "unauthRoleName": {
            "Type": "String"
        },
        "adminAuthProtected": {
			"Type": "String"
		},
        "adminGuestProtected": {
            "Type": "String"
        },
        "identifyType": {
            "Type": "String"
        },<% if (props.identifyType === "identifyEntities") { %>
        "celebrityDetectionEnabled": {
            "Type": "String"
        },
        "adminTask": {
            "Type": "String"
        },
        "maxEntities": {
            "Type": "Number"
        },
        "folderPolicies": {
            "Type": "String"
        },<% } %><% if (props.identifyType === "identifyText") { %>
        "identifyDoc": {
            "Type": "String"
        },
        "format": {
            "Type": "String"
        },<% } %><% if (props.identifyType === "identifyLabels") { %>
        "type": {
            "Type": "String"
        },<% } %>
        "env": {
            "Type": "String"
        }<%if (props.dependsOn && props.dependsOn.length > 0) { %>,<% } %>
        <% if (props.dependsOn) { %>
        <% for(var i=0; i < props.dependsOn.length; i++) { %>
        <% for(var j=0; j < props.dependsOn[i].attributes.length; j++) { %>
            "<%= props.dependsOn[i].category %><%= props.dependsOn[i].resourceName %><%= props.dependsOn[i].attributes[j] %>": {
                "Type": "String",
                "Default": "<%= props.dependsOn[i].category %><%= props.dependsOn[i].resourceName %><%= props.dependsOn[i].attributes[j] %>"
            }<%if (i !== props.dependsOn.length - 1 || j !== props.dependsOn[i].attributes.length - 1) { %>,<% } %>
            <% } %>
            <% } %>
        <% } %>
    },
    "Conditions" :{
        "CreateAdminAuthProtected": {
                    "Fn::Not" : [{
                        "Fn::Equals" : [
                        {"Ref" : "adminAuthProtected"},
                        "DISALLOW"
                ]
            }]
        },
        "CreateAdminGuestProtected": {
                "Fn::Not" : [{
                    "Fn::Equals" : [
                        {"Ref" : "adminGuestProtected"},
                        "DISALLOW"
                ]
            }]
        },
        "ShouldNotCreateEnvResources": {
            "Fn::Equals": [
                {
                    "Ref": "env"
                },
                "NONE"
            ]
        },
        "AuthGuestRoleAccess":{
            "Fn::Equals": [{"Ref":"access"}, "authAndGuest"]
        }
    },
    "Outputs": {
        "region": {
            "Value": {
                "Fn::FindInMap": [
                    "RegionMapping",
                    { "Ref" : "AWS::Region" },
                    { "Ref": "identifyType" }
                ]
            }
        },<% if (props.adminTask === true) { %>
        "collectionId": {
            "Value": {
                "Fn::If": [
                            "ShouldNotCreateEnvResources",
                            {
                                "Ref": "resourceName"
                            },
                            {

                                "Fn::Join": [
                                    "",
                                    [
                                      {
                                        "Ref": "resourceName"
                                      },
                                      "-",
                                      {
                                        "Ref": "env"
                                      }
                                    ]
                                ]
                            }
                        ]
            }
        },<% } %><% if (props.identifyType === "identifyText") { %>
        "format": {
            "Value": {"Ref": "format"}
        }<% } %><% if (props.identifyType === "identifyEntities") { %>
        "celebrityDetectionEnabled" : {
            "Value" : {"Ref": "celebrityDetectionEnabled"}
        },"maxEntities": {
            "Value" : {"Ref": "maxEntities"}
        }<% } %><% if (props.identifyType === "identifyLabels") { %>
        "type": {
            "Value" : {"Ref": "type"}
        }<% } %>
    },
    "Resources": {
        <% if (props.folderPolicies === "app") { %>
        "S3AuthPredicitionsAdminProtectedPolicy": {
			"Condition": "CreateAdminAuthProtected",
			"Type": "AWS::IAM::Policy",
			"Properties": {
				"PolicyName": "S3RekognitionAuthAdminFolderAccess",
				"Roles": [
					{
                        "Ref": "authRoleName"
					}
				],
				"PolicyDocument": {
					"Version": "2012-10-17",
					"Statement": [
						{
							"Effect": "Allow",
							"Action": ["s3:DeleteObject","s3:GetObject","s3:PutObject"],
							"Resource": [
								{
									"Fn::Join": [
										"",
										[
											"arn:aws:s3:::",
											{
											    "Ref": "storage<%= props.storageResourceName %>BucketName"
											},
											"/protected/predictions/index-faces/${cognito-identity.amazonaws.com:sub}/*"
										]
									]
								}
							]
						}
					]
				}
			}
        },
        <% } %>
        <% if (props.folderPolicies === "app") { %>
		"S3GuestPredicitionsAdminPublicPolicy": {
			"Condition": "CreateAdminGuestProtected",
			"Type": "AWS::IAM::Policy",
			"Properties": {
				"PolicyName": "S3RekognitionGuestAdminFolderAccess",
				"Roles": [
					{
					    "Ref": "unauthRoleName"
					}
				],
				"PolicyDocument": {
					"Version": "2012-10-17",
					"Statement": [
						{
							"Effect": "Allow",
							"Action": ["s3:DeleteObject","s3:GetObject","s3:PutObject"],
							"Resource": [
								{
									"Fn::Join": [
										"",
										[
											"arn:aws:s3:::",
											{
											    "Ref": "storage<%= props.storageResourceName %>BucketName"
											},
											"/protected/predictions/index-faces/${cognito-identity.amazonaws.com:sub}/*"
										]
									]
								}
							]
						}
					]
				}
			}
        },
        <% } %>
        <% if (props.functionName) { %>
        "LambdaRekognitionAccessPolicy": {
            "Type": "AWS::IAM::Policy",
            "Properties": {
                "PolicyName": "amplify-lambda-execution-rekognition-policy",
                "Roles": [
                    {
                        "Ref": "function<%= props.functionName %>LambdaExecutionRole"
                    }
                ],
                "PolicyDocument": {
                    "Version": "2012-10-17",
                    "Statement": [
                        {
                            "Effect": "Allow",
                            "Action": [
                                "rekognition:ListFaces",
                                "rekognition:IndexFaces",
                                "rekognition:DeleteFaces"
                            ],
                            "Resource": [
                                {
                                    "Fn::Join": [
                                        "",
                                        [
                                            "arn:aws:rekognition:",
                                            {
                                                "Ref" : "AWS::Region"
                                            },
                                            ":",
                                            {
                                                "Ref": "AWS::AccountId"
                                            },
                                            ":",
                                            "collection/",
                                            {
                                                "Fn::If": [
                                                    "ShouldNotCreateEnvResources",
                                                    {
                                                        "Ref": "resourceName"
                                                    },
                                                    {

                                                        "Fn::Join": [
                                                            "",
                                                            [
                                                              {
                                                                "Ref": "resourceName"
                                                              },
                                                              "-",
                                                              {
                                                                "Ref": "env"
                                                              }
                                                            ]
                                                        ]
                                                    }
                                                ]
                                            }
                                        ]
                                    ]
                                }
                            ]
                        }
                    ]
                }
            }
        },
        <% } %>
        <% if (props.adminTask === true) { %>
            "CollectionCreationFunction": {
                "Type": "AWS::Lambda::Function",
                "Properties": {
                    "Code": {
                        "ZipFile": {
                            "Fn::Join": [
                                "\n",
                                [
                                    "const response = require('cfn-response');",
                                    "const { RekognitionClient, CreateCollectionCommand, DeleteCollectionCommand, ListCollectionsCommand } = require('@aws-sdk/client-rekognition');",
                                    "const { S3Client, PutObjectCommand } = require('@aws-sdk/client-s3');",
                                    "let responseData = {};",
                                    "exports.handler = function(event, context) {",
                                    "    // Don't return promise, response.send() marks context as done internally",
                                    "    const ignoredPromise = handleEvent(event, context)",
                                    "};",
                                    "async function handleEvent(event, context) {",
                                    "    try {",
                                    "        if (event.RequestType === 'Delete') {",
                                    "            try {",
                                    "                let params = {",
                                    "                    CollectionId: event.ResourceProperties.collectionId",
                                    "                };",
                                    "                const rekognition = new RekognitionClient({region: event.ResourceProperties.region});",
                                    "                const res = await rekognition.send(new DeleteCollectionCommand(params));",
                                    "                console.log('delete' + res);",
                                    "                console.log('response data' + JSON.stringify(res));",
                                    "                response.send(event, context, response.SUCCESS, res);",
                                    "            } catch(err) {",
                                    "                if (err.name !== 'NotFoundException') {",
                                    "                    response.send(event, context, response.FAILED);",
                                    "                } else {",
                                    "                    response.send(event, context, response.SUCCESS);",
                                    "                }",
                                    "            }",
                                    "        } else if (event.RequestType === 'Update' || event.RequestType === 'Create') {",
                                    "            const collectionId = event.ResourceProperties.collectionId;",
                                    "            const params = {",
                                    "                CollectionId: collectionId",
                                    "            };",
                                    "            const rekognition = new RekognitionClient({ region: event.ResourceProperties.region });",
                                    "            const res = await rekognition.send(new ListCollectionsCommand({}));",
                                    "            let CollectionIds = res.CollectionIds ?? [];",
                                    "            console.log('CollectionIds' + CollectionIds);",
                                    "            if(CollectionIds.indexOf(collectionId) !== -1) {",
                                    "                response.send(event, context, response.SUCCESS, responseData);",
                                    "            } else {",
                                    "                responseData = await rekognition.send(new CreateCollectionCommand(params));",
                                    "                console.log('responseData' + JSON.stringify(responseData)); console.log(collectionId);",
                                    "                let s3 = new S3Client({});",
                                    "                let s3params = {",
                                    "                    Bucket: event.ResourceProperties.bucketName,",
                                    "                    Key: 'protected/predictions/index-faces/admin/'",
                                    "                };",
                                    "                const s3Res = await s3.send(new PutObjectCommand(s3params));",
                                    "                if (s3Res.ETag) {",
                                    "                    response.send(event, context, response.SUCCESS, responseData);",
                                    "                }",
                                    "                else {",
                                    "                    response.send(event, context, response.FAILED, s3Res);",
                                    "                }",
                                    "            }",
                                    "        }",
                                    "    } catch(err) {",
                                    "        console.log(err.stack);",
                                    "        response.send(event, context, response.FAILED, {Error: err});",
                                    "    }",
                                    "}"
                                ]
                            ]
                        }
                    },
                    "Handler": "index.handler",
                    "Runtime": "nodejs22.x",
                    "Timeout": 300,
                    "Role": {
                        "Fn::GetAtt": [
                            "CollectionsLambdaExecutionRole",
                            "Arn"
                        ]
                    }
                }
            },
            "CollectionFunctionOutputs": {
                "Type": "Custom::LambdaCallout",
                "Properties": {
                    "ServiceToken": {
                        "Fn::GetAtt": [
                            "CollectionCreationFunction",
                            "Arn"
                        ]
                    },
                    "region": {
                        "Ref" : "AWS::Region"
                    },
                    "collectionId": {
                            "Fn::If": [
                                "ShouldNotCreateEnvResources",
                                {
                                    "Ref": "resourceName"
                                },
                                {

                                    "Fn::Join": [
                                        "",
                                        [
                                        {
                                            "Ref": "resourceName"
                                        },
                                        "-",
                                        {
                                            "Ref": "env"
                                        }
                                        ]
                                    ]
                                }
                            ]
                        },
                        "bucketName": {
                            "Ref": "storage<%= props.storageResourceName %>BucketName"
                        }
                }
            },
            "CollectionsLambdaCloudWatchPolicy": {
                "Type": "AWS::IAM::Policy",
                "Properties": {
                    "PolicyName": {
                        "Ref": "resourceName"
                    },
                    "Roles": [
                        {
                            "Ref": "CollectionsLambdaExecutionRole"
                        }
                    ],
                    "PolicyDocument": {
                        "Version": "2012-10-17",
                        "Statement": [
                            {
                                "Effect": "Allow",
                                "Action": [
                                    "logs:CreateLogGroup",
                                    "logs:CreateLogStream",
                                    "logs:PutLogEvents"
                                ],
                                "Resource": {
                                    "Fn::Sub": [
                                        "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/${lambdaName}:log-stream:*",
                                        {
                                            "lambdaName": {
                                                "Ref": "CollectionCreationFunction"
                                            }
                                        }
                                    ]
                                }
                            }
                        ]
                    }
                }
            },
            "CollectionsLambdaExecutionRole": {
                "Type": "AWS::IAM::Role",
                "Properties": {
                    "RoleName": {
                        "Fn::If": [
                            "ShouldNotCreateEnvResources",
                            {
                                "Ref": "resourceName"
                            },
                            {

                                "Fn::Join": [
                                    "",
                                    [
                                      {
                                        "Ref": "resourceName"
                                      },
                                      "-",
                                      {
                                        "Ref": "env"
                                      }
                                    ]
                                ]
                            }
                        ]
                    },
                    "AssumeRolePolicyDocument": {
                        "Version": "2012-10-17",
                        "Statement": [
                            {
                                "Effect": "Allow",
                                "Principal": {
                                    "Service": [
                                        "lambda.amazonaws.com"
                                    ]
                                },
                                "Action": [
                                    "sts:AssumeRole"
                                ]
                            }
                        ]
                    },
                    "Policies": [
                        {
                            "PolicyName": {
                                "Ref": "identifyPolicyName"
                            },
                            "PolicyDocument": {
                                "Version": "2012-10-17",
                                "Statement": [
                                {
                                    "Effect": "Allow",
                                    "Action": [
                                      "rekognition:CreateCollection",
                                      "rekognition:DeleteCollection",
                                      "s3:PutObject"
                                    ],
                                    "Resource": [
                                    {
                                        "Fn::Join": [
                                        "", [
                                          "arn:aws:rekognition:",
                                          { "Ref": "AWS::Region" },
                                          ":",
                                          { "Ref": "AWS::AccountId" },
                                          ":",
                                          "collection/",
                                          {
                                            "Fn::If": [
                                                "ShouldNotCreateEnvResources",
                                                {
                                                    "Ref": "resourceName"
                                                },
                                                {

                                                    "Fn::Join": [
                                                        "",
                                                        [
                                                          {
                                                            "Ref": "resourceName"
                                                          },
                                                          "-",
                                                          {
                                                            "Ref": "env"
                                                          }
                                                        ]
                                                    ]
                                                }
                                            ]
                                        }
                                        ]
                                      ]
                                    },
                                    {
                                      "Fn::Join": [
                                        "",
                                        [
                                          "arn:aws:s3:::",
                                          {
                                            "Ref": "storage<%= props.storageResourceName %>BucketName"
                                          },
                                          "/*"
                                        ]
                                      ]
                                    }
                                    ]
                                },
                                {
                                  "Effect": "Allow",
                                  "Action": [
                                    "rekognition:ListCollections"
                                  ],
                                  "Resource": "*"
                                }
                              ]
                            }
                        }
                    ]
                }
            },
            "IdentifyEntitiesSearchFacesPolicy": {
                "Type": "AWS::IAM::Policy",
                "Properties": {
                    "PolicyName": {
                        "Fn::Join": [
                          "", [{ "Ref":"identifyPolicyName" }, "-", "searchFaces" ]
                        ]
                    },
                    "Roles": {
                        "Fn::If": [
                            "AuthGuestRoleAccess",
                            [{"Ref": "authRoleName"}, {"Ref": "unauthRoleName"}],
                            [{"Ref": "authRoleName"}]
                        ]
                    },
                    "PolicyDocument": {
                        "Version": "2012-10-17",
                        "Statement": [
                            {
                                "Effect": "Allow",
                                "Action": [
                                    "rekognition:SearchFacesByImage"
                                ],
                                "Resource": [
                                {
                                    "Fn::Join": [
                                        "",
                                        [
                                            "arn:aws:rekognition:",
                                            {
                                                "Ref" : "AWS::Region"
                                            },
                                            ":",
                                            {
                                                "Ref": "AWS::AccountId"
                                            },
                                            ":",
                                            "collection/",
                                            {
                                                "Fn::If": [
                                                    "ShouldNotCreateEnvResources",
                                                    {
                                                        "Ref": "resourceName"
                                                    },
                                                    {

                                                        "Fn::Join": [
                                                            "",
                                                            [
                                                              {
                                                                "Ref": "resourceName"
                                                              },
                                                              "-",
                                                              {
                                                                "Ref": "env"
                                                              }
                                                            ]
                                                        ]
                                                    }
                                                ]
                                            }
                                        ]
                                    ]
                                }
                            ]
                            }
                        ]
                    }
                }
            },
        <% } %>
        <% if (props.identifyType === "identifyText") { %>
        "IdentifyTextPolicy": {
            "Type": "AWS::IAM::Policy",
            "Properties": {
                "PolicyName": { "Ref":"identifyPolicyName" },
                "Roles": {
                    "Fn::If": [
                        "AuthGuestRoleAccess",
                        [{"Ref": "authRoleName"}, {"Ref": "unauthRoleName"}],
                        [{"Ref": "authRoleName"}]
                    ]
                },
                "PolicyDocument": {
                    "Version": "2012-10-17",
                    "Statement": [
                        {
                            "Effect": "Allow",
                            "Action": [
                                "rekognition:DetectText",
                                "rekognition:DetectLabel"<% if (props.identifyDoc) { %>,
                                "textract:AnalyzeDocument",
                                "textract:DetectDocumentText",
                                "textract:GetDocumentAnalysis",
                                "textract:StartDocumentAnalysis",
                                "textract:StartDocumentTextDetection"<% } %>
                            ],
                            "Resource": "*"
                        }
                    ]
                }
            }
        }<% } %><% if (props.identifyType === "identifyEntities") { %>
        "IdentifyEntitiesPolicy": {
            "Type": "AWS::IAM::Policy",
            "Properties": {
                "PolicyName": { "Ref":"identifyPolicyName" },
                "Roles": {
                    "Fn::If": [
                        "AuthGuestRoleAccess",
                        [{"Ref": "authRoleName"}, {"Ref": "unauthRoleName"}],
                        [{"Ref": "authRoleName"}]
                    ]
                },
                "PolicyDocument": {
                    "Version": "2012-10-17",
                    "Statement": [
                        {
                            "Effect": "Allow",
                            "Action": [
                                "rekognition:DetectFaces",
                                "rekognition:RecognizeCelebrities"
                            ],
                            "Resource": "*"
                        }
                    ]
                }
            }
        }<% } %><% if (props.identifyType === "identifyLabels") { %>
        "identifyLabelssPolicy": {
            "Type": "AWS::IAM::Policy",
            "Properties": {
                "PolicyName": { "Ref":"identifyPolicyName" },
                "Roles": {
                    "Fn::If": [
                        "AuthGuestRoleAccess",
                        [{"Ref": "authRoleName"}, {"Ref": "unauthRoleName"}],
                        [{"Ref": "authRoleName"}]
                    ]
                },
                "PolicyDocument": {
                    "Version": "2012-10-17",
                    "Statement": [
                        {
                            "Effect": "Allow",
                            "Action": [
                                "rekognition:DetectLabels",
                                "rekognition:DetectModerationLabels"
                            ],
                            "Resource": "*"
                        }
                    ]
                }
            }
        }<% } %>
    }
}
